import { mapState, mapActions } from 'pinia';
import { useStore } from 'stores/store';
import { encrypt, decrypt } from 'app/src-ssr/util/crypto.js';

/**
 * 装配查询条件
 * @param {*} configData 配置数据
 * @param {*} searchBoard 载体面板
 */
function assemblyFunc (configData, searchBoard) {
  configData.forEach(item => {
    searchBoard[item.name] = {
      type: item.type,
      label: item.label,
      value: item.default || '',
      hide: !!item.hide,
      readonly: !!item.readonly,
      hint: item.hint || ''
    }
    if (item.type === 'select') {
      searchBoard[item.name].dict = item.dict || '';
      searchBoard[item.name].options = item.options || [];
      searchBoard[item.name].selected = item.selected || [];
      searchBoard[item.name].clearable = item.clearable === undefined ? true : item.clearable;
      searchBoard[item.name].default = item.default || '';
    } else if (item.type === 'autocomplete') {
      searchBoard[item.name].options = [];
      if (item.dict) {
        searchBoard[item.name].dict = item.dict;
      }
    } else if (item.type === 'date' && item.default) {
      searchBoard[item.name].value = '';
      searchBoard[item.name].days = item.default;
      searchBoard[item.name].clearable = item.clearable;
    } else if (item.type === 'toggle') {
      if (item.trueValue !== undefined) searchBoard[item.name].trueValue = item.trueValue;
      if (item.trueLabel !== undefined) searchBoard[item.name].trueLabel = item.trueLabel;
      if (item.falseValue !== undefined) searchBoard[item.name].falseValue = item.falseValue;
      if (item.falseLabel !== undefined) searchBoard[item.name].falseLabel = item.falseLabel;
    } else if (item.type === 'treeSelect') {
      searchBoard[item.name].includeRoot = item.includeRoot;
      searchBoard[item.name].dense = item.dense;
      searchBoard[item.name].key = item.key;
      searchBoard[item.name].index = item.index;
      searchBoard[item.name].options = item.options;
    }
  });
}

// 索引页用到的通用功能
export const indexPageMix = {
  data () {
    return {
      taskNumber: 0
    };
  },
  methods: {
    ...mapActions(useStore, ['initDictionary']),
    initDict (typeList) { // 初始化字典
      let types = typeList;
      if (typeof typeList === 'string') types = [types];

      return new Promise(resolve => {
        this.$axios.post('/c/system/getDataDict', { types }).then(({ data }) => {
          this.initDictionary(data);
          resolve();
        });
      });
    },
    refreshTaskNumber () { // 刷新任务数量
      if (this.taskNumApi) {
        this.$axios.get(this.taskNumApi).then(({ data }) => {
          this.taskNumber = data.taskNumber;
        });
      }
    }
  }
};

// 列表页用到的通用功能
export const listPageMix = {
  inject: ['confirmBox'],
  data () {
    return {
      loading: false,
      pagination: {
        sortBy: 'id',
        descending: true,
        page: 1,
        rowsPerPage: 25,
        rowsNumber: 0
      },
      data: [],
      summary: null,
      visibleColumns: [],
      searchList: {}, // 搜索列表配置
      moduleName: '', // 模块名
      submoduleName: '', // 子模块名
      grid: false,
      approvalNumber: 0, // 待审批数量
      adjustNumber: 0 // 审批被拒待调整数量
    }
  },
  created () {
    this.$nextTick(() => {
      this.grid = this.$q.screen.xs;
    });
  },
  mounted () {
    this.restoreParams();

    this.search();
    this.restoreScrollTop();
  },
  methods: {
    ...mapActions(useStore, ['saveSearchParam', 'saveScrollTop', 'restoreScrollTop', 'initDictionary']),
    initDict (typeList) { // 初始化字典
      let types = typeList;
      if (typeof typeList === 'string') types = [types];

      return new Promise(resolve => {
        this.$axios.post('/c/system/getDataDict', { types }).then(({ data }) => {
          this.initDictionary(data);
          resolve();
        });
      });
    },
    onRequest (props) {
      const { page, rowsPerPage, sortBy, descending } = props.pagination;
      const filter = props.filter;

      this.loading = true;

      const startRow = (page - 1) * rowsPerPage;
      const count = rowsPerPage;
      this.$axios.post(this.listApi, { startRow, count, filter, sortBy, descending, columns: this.visibleColumns }).then(({ data }) => {
        this.pagination.rowsNumber = data.rowsNumber;
        this.data = data.data;
        this.pagination.page != page && window.scrollTo(0, 0);// 回到顶部
        this.pagination.page = page;
        this.pagination.rowsPerPage = rowsPerPage;
        this.pagination.sortBy = sortBy;
        this.pagination.descending = descending;
        this.loading = false;

        if (this.data && this.data.length > 0) {
          this.data.forEach(item => {
            item._hidden = false;
          });
        }

        if (data.summary) this.summary = data.summary;
      });
      this.refreshTaskNumber();
    },
    restoreParams () { // 恢复页面参数
      if (this.$q.localStorage.getItem(`${this.pageKeyWord}Fields`)) { // 恢复可见列
        this.visibleColumns = [...this.$q.localStorage.getItem(`${this.pageKeyWord}Fields`).filter(v => this.columns.findIndex(c => c.name === v) >= 0)];
      } else if (this.visibleColumns.length === 0) {
        this.visibleColumns = this.columns.map(v => v.name);
      }

      if (this.$route.query.back === 'true' && this.searchParam[this.pageKeyWord]) {
        this.pagination = Object.assign({}, this.searchParam[this.pageKeyWord].pagination);
        this.filter = Object.assign({}, this.searchParam[this.pageKeyWord].filter);
      }
    },
    goDetail (id, query) { // 跳转到明细
      const para = {};
      const route = {};

      para[this.pageKeyWord] = {
        pagination: this.pagination,
        filter: this.filter
      };
      if (query) {
        para[this.pageKeyWord].query = query;
        route.query = query;
      }

      this.saveSearchParam(para);
      this.saveScrollTop();

      const path = this.$route.path.split('/');
      path[path.length - 1] = 'detail';
      path.push(encrypt(String(id), this.secretKey));

      route.path = path.join('/');
      // const route = { path: path.join('/') };

      this.$router.push(route);
    },
    deleteDetail (id) { // 删除明细
      this.confirmBox('删除', '确定删除该条记录吗？').then(confirm => {
        if (confirm) {
          this.$axios.post(this.deleteApi, { id }).then(res => {
            if (res.data.result === 'fail') {
              this.$q.notify({
                message: res.data.message || '删除失败',
                color: 'negative',
                icon: 'error',
                position: 'top',
                timeout: 5000,
                html: res.data.message && res.data.message.indexOf('<br>') >= 0
              });
            } else {
              this.$q.notify({
                message: '删除成功',
                color: 'secondary',
                icon: 'done',
                position: 'top',
                timeout: 2000
              });
              this.search();
            }
          });
        }
      });
    },
    search () {
      this.onRequest({
        pagination: this.pagination,
        filter: this.filter
      });
    },
    assembly (configData) {
      assemblyFunc(configData, this.searchList);
    },
    shareFunc (row, subField) {
      if (!this.shareApi) {
        return;
      }

      this.$axios.post(this.shareApi, { id: row.id }).then(({ data }) => {
        if (data.result === 'fail') {
          this.$q.notify({
            message: data.message || '获取链接失败',
            color: 'negative',
            icon: 'error',
            position: 'top',
            timeout: 5000
          });
        } else {
          this.share.id = row.id;
          this.share.title = '分享' + this.modelLabel;
          this.share.codeTitle = this.modelLabel + ':' + row.bill_no;
          this.share.codeSubTitle = row[subField] || '';
          this.share.url = data.url;
          this.share.email = !!row.email;
          this.$refs.share.show();
        }
      });
    },
    refreshTaskNumber () { // 刷新任务数量
      if (this.taskNumApi) {
        this.$axios.get(this.taskNumApi).then(({ data }) => {
          this.approvalNumber = data.approvalNumber;
          this.adjustNumber = data.adjustNumber;
        });
      }
    },
    viewApproval () { // 查看待审批的数据
      this.onRequest({
        pagination: this.pagination,
        filter: {
          approval_user_id: this.userInfo.userid,
          approval_state: 'none'
        }
      });
    },
    viewAdjust () { // 查看审批被拒待调整的数据
      this.onRequest({
        pagination: this.pagination,
        filter: {
          create_user_id: this.userInfo.userid,
          approval_state: 'reject'
        }
      });
    }
  },
  computed: {
    ...mapState(useStore, ['dictionary', 'searchParam', 'dictObj', 'userInfo', 'rights', 'defaultImg', 'secretKey', 'siteInfo']),
    pageKeyWord () {
      const path = this.$route.path.split('/');
      const key = path.length > 2 ? path[2] : '';
      return `${key}${this.moduleName}${this.submoduleName}`;
    },
    filter: { // 过滤器
      get () {
        const filter = {};
        for (const field in this.searchList) {
          filter[field] = this.searchList[field].value
        }
        return filter;
      },
      set (val) {
        if (typeof val === 'object') {
          for (const field in val) {
            this.searchList[field].value = val[field];
          }
        }
      }
    }
  },
  watch: {
    visibleColumns (val) { // 本地保存可见列
      this.$q.localStorage.set(`${this.pageKeyWord}Fields`, val);
    }
  }
};

// 明细页混合
export const detailPageMix = {
  inject: ['confirmBox', 'inputBox'],
  data () {
    return {
      mode: '',
      id: '',
      idEx: [], // 扩展id，克隆时用
      saving: false,
      loading: false,
      data: {
        create_user_id: '',
        approval_user_id: '',
        approval_state: 'none',
        _owner: false
      }
    }
  },
  mounted () {
    if (this.$route.params.id) {
      const id = decrypt(this.$route.params.id, this.secretKey).split(',');
      this.id = Number(id[0]);

      if (id.length > 1) {
        this.idEx = id.slice(1);
      }
    }

    this.mode = this.id < 0 ? 'add' : 'edit';
  },
  methods: {
    ...mapActions(useStore, ['getTask', 'initDictionary']),
    initDict (typeList) { // 初始化字典
      let types = typeList;
      if (typeof typeList === 'string') types = [types];

      return new Promise(resolve => {
        this.$axios.post('/c/system/getDataDict', { types }).then(({ data }) => {
          this.initDictionary(data);
          resolve();
        });
      });
    },
    // 提取数据
    refreshData (cb) {
      this.loading = true;
      this.$axios.post(this.detailApi, { id: this.id }).then(({ data }) => {
        this.data = data;
        for (const key in data) {
          if (this.formFields[key]) {
            this.formFields[key].value = data[key];
          }
        }

        if (cb && typeof cb === 'function') {
          cb();
        }
        this.setReadonly();
        this.$nextTick(() => {
          // if (cb) { // 有回调，则不写，让回调来调整该参数
          this.loading = false;
          // }
        });
      });
    },
    saveData (submitData, cb) { // 保存数据
      // 处理数据
      let formData = {};
      if (!submitData) {
        for (const field in this.formFields) {
          if (this.formFields[field].type === 'select' && typeof this.formFields[field].value === 'object' && this.formFields[field].value) {
            this.data[field] = formData[field] = this.formFields[field].value.value;
          } else {
            this.data[field] = formData[field] = this.formFields[field].value;
          }
        }
      } else {
        formData = submitData;
      }

      this.$axios.post(this.mode === 'add' ? this.createApi : this.updateApi, { id: this.id, formData }).then(({ data }) => {
        this.saving = false;
        if (data.result === 'fail') {
          this.$q.notify({
            message: data.message || '保存失败',
            color: 'negative',
            icon: 'error',
            position: 'top',
            timeout: 5000,
            html: data.message && data.message.indexOf('<br>') >= 0
          });
        } else {
          this.$q.notify({
            message: '保存成功',
            color: 'secondary',
            icon: 'done',
            position: 'top',
            timeout: 2000
          });
          if (cb && typeof cb === 'function') {
            cb(null, { id: data.id, encryptId: encrypt(String(data.id), this.secretKey) });
          } else {
            this.onReset();
          }
        }
      });
    },
    setReadonly () { // 不可保存，设置只读
      this.$nextTick(() => {
        if (!this.canSave) {
          Object.keys(this.formFields).forEach(key => {
            if (this.formFields[key].type == 'table') {
              this.formFields[key].editmode = [];
            } else if (this.formFields[key].readonly !== undefined) {
              this.formFields[key].readonly = true;
            }
          });
        }
      });
    },
    onReset () { // 返回列表页
      this.$router.push({ path: `/main/${this.pageKeyWord}`, query: { back: 'true' } });// 返回标记，用于恢复表格参数
    },
    async getTaskData (ids, query) { // 取任务数据
      if (this.taskApi && ids && ids.length > 0) {
        let api = this.taskApi;
        if (query) {
          api = this.taskApi + '?' + query;
        }
        const { data } = await this.$axios.post(api, { filter: { ids } });
        return data.data;
      } else {
        return [];
      }
    },
    assembly (configData, searchBoard) { // 装配查询条件
      assemblyFunc(configData, searchBoard);
    }
  },
  computed: {
    ...mapState(useStore, ['dictionary', 'dictObj', 'userInfo', 'rights', 'defaultImg', 'secretKey']),
    pageKeyWord () {
      const path = this.$route.path.split('/');
      return path.length > 2 ? path[2] : '';
    },
    canSave () {
      let flag = false;
      if (this.mode === 'add') { // 若是新增，有新增权限即可
        flag = this.rights[this.moduleName] && this.rights[this.moduleName].add;
      } else if (this.mode === 'edit') { // 若是修改，要么有修改权限，要么是拥有者
        flag = (this.rights[this.moduleName] && this.rights[this.moduleName].edit) || this.data._owner;
      }
      return flag;
    },
    historyData () { // 历史数据
      const his = JSON.parse(JSON.stringify(this?.data?.history || []));
      his.sort((a, b) => b.time - a.time); // 倒序
      return his;
    },
    historyEscape () { // 转义字段
      const escapeFields = {};
      for (const key in this.formFields) {
        if (['select', 'date', 'image', 'attach'].includes(this.formFields[key].type)) {
          escapeFields[key] = this.formFields[key];
        }
      }
      return escapeFields;
    },
    tableFields () { // 表格的字段
      const fields = {};
      for (const key in this.formFields) {
        if (this.formFields[key].type === 'table') {
          fields[key] = this.formFields[key];
        }
      }
      return fields;
    }
  }
};

// 任务混合页
export const taskPageMix = {
  emits: ['do'],
  data () {
    return {
      loading: false,
      pagination: {
        sortBy: 'id',
        descending: true,
        page: 1,
        rowsPerPage: 25,
        rowsNumber: 0
      },
      data: [],
      visibleColumns: [],
      searchList: {}, // 搜索列表配置
      moduleName: '', // 模块名
      submoduleName: '', // 子模块名
      grid: false,
      selected: []
    }
  },
  created () {
    this.$nextTick(() => {
      this.grid = this.$q.screen.xs;
    });
  },
  mounted () {
    this.restoreParams();

    this.search();
    this.restoreScrollTop();
  },
  methods: {
    ...mapActions(useStore, ['saveSearchParam', 'saveScrollTop', 'restoreScrollTop', 'initDictionary', 'setTask']),
    initDict (typeList) { // 初始化字典
      let types = typeList;
      if (typeof typeList === 'string') types = [types];

      return new Promise(resolve => {
        this.$axios.post('/c/system/getDataDict', { types }).then(({ data }) => {
          this.initDictionary(data);
          resolve();
        });
      });
    },
    onRequest (props) {
      const { page, rowsPerPage, sortBy, descending } = props.pagination;
      const filter = props.filter;

      this.loading = true;
      let api = this.taskApi;
      if (this.query) {
        api = this.taskApi + '?' + this.query.map(v => `${v[0]}=${v[1]}`).join('&');
      }

      const startRow = (page - 1) * rowsPerPage;
      const count = rowsPerPage;
      this.$axios.post(api, { startRow, count, filter, sortBy, descending, columns: this.visibleColumns }).then(({ data }) => {
        this.pagination.rowsNumber = data.rowsNumber;
        this.data = data.data;
        this.pagination.page != page && window.scrollTo(0, 0);// 回到顶部
        this.pagination.page = page;
        this.pagination.rowsPerPage = rowsPerPage;
        this.pagination.sortBy = sortBy;
        this.pagination.descending = descending;
        this.loading = false;

        if (this.data && this.data.length > 0) {
          this.data.forEach(item => {
            item._hidden = false;
          });
        }

        if (data.summary) this.summary = data.summary;
      });
    },
    restoreParams () { // 恢复页面参数
      if (this.$q.localStorage.getItem(`${this.pageKeyWord}Fields`)) { // 恢复可见列
        this.visibleColumns = [...this.$q.localStorage.getItem(`${this.pageKeyWord}Fields`).filter(v => this.columns.findIndex(c => c.name === v) >= 0)];
      } else if (this.visibleColumns.length === 0) {
        this.visibleColumns = this.columns.map(v => v.name);
      }

      if (this.$route.query.back === 'true' && this.searchParam[this.pageKeyWord]) {
        this.pagination = Object.assign({}, this.searchParam[this.pageKeyWord].pagination);
        this.filter = Object.assign({}, this.searchParam[this.pageKeyWord].filter);
      }
    },
    doTask () { // 跳转到明细
      if (this.selected.length === 0) {
        return;
      }
      const ids = this.selected.map(item => item.id);
      this.selected = [];

      const para = {};
      para[this.pageKeyWord] = {
        pagination: this.pagination,
        filter: this.filter
      };

      this.saveSearchParam(para);
      this.saveScrollTop();

      if (this.query && this.query[0] && this.query[0][1]) {
        ids.push(`${this.query[0][0]}=${this.query[0][1]}`);
      }

      this.setTask(this.moduleName, ids);

      const path = ['', 'main', this.moduleName, 'detail', encrypt(String(-1), this.secretKey)];
      this.$router.push({ path: path.join('/') });
      this.$emit('do', ids);
    },
    search () {
      this.onRequest({
        pagination: this.pagination,
        filter: this.filter
      })
    },
    assembly (configData) {
      assemblyFunc(configData, this.searchList);
    }
  },
  computed: {
    ...mapState(useStore, ['dictionary', 'searchParam', 'dictObj', 'userInfo', 'rights', 'defaultImg', 'secretKey', 'siteInfo']),
    pageKeyWord () {
      const path = this.$route.path.split('/');
      const key = path.length > 2 ? path[2] : '';
      return `${key}${this.moduleName}${this.submoduleName}`;
    },
    filter: { // 过滤器
      get () {
        const filter = {};
        for (const field in this.searchList) {
          filter[field] = this.searchList[field].value
        }
        return filter;
      },
      set (val) {
        if (typeof val === 'object') {
          for (const field in val) {
            this.searchList[field].value = val[field];
          }
        }
      }
    }
  },
  watch: {
    visibleColumns (val) { // 本地保存可见列
      this.$q.localStorage.set(`${this.pageKeyWord}Fields`, val);
    }
  }
};
